var serverSystem = server.registerSystem(0, 0);


serverSystem.initialize = function () {
    const scriptLoggerConfig = serverSystem.createEventData("minecraft:script_logger_config");
    scriptLoggerConfig.data.log_errors = true;
    scriptLoggerConfig.data.log_information = true;
    scriptLoggerConfig.data.log_warnings = true;
    serverSystem.broadcastEvent("minecraft:script_logger_config", scriptLoggerConfig);
    serverSystem.players = {};
    serverSystem.listenForEvent("minecraft:player_placed_block", eventData => serverSystem.blockPlace(eventData));
};


serverSystem.blockPlace = function (eventData) {
    if (serverSystem.getComponent(eventData.data.player, "minecraft:hand_container").data[0].item == "block:fillair" || serverSystem.getComponent(eventData.data.player, "minecraft:hand_container").data[0].item == "block:setcoords" || serverSystem.getComponent(eventData.data.player, "minecraft:hand_container").data[0].item == "block:hollow") {
        serverSystem.executeCommand("/setblock " + eventData.data.block_position.x + " " + eventData.data.block_position.y + " " + eventData.data.block_position.z + " air 0", () => { });
    }

    if (!(String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name) in serverSystem.players)) {
        serverSystem.players[String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name)] = {
            "fp": [],
            "sp": [],
            "hl": false
        };
    }
    //for setting coordinates
    if (serverSystem.getComponent(eventData.data.player, "minecraft:hand_container").data[0].item == "block:setcoords") {
        if (serverSystem.players[String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name)].fp.length != 0 && serverSystem.players[String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name)].sp.length != 0) {
            //resets coords
            serverSystem.players[String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name)].fp = [];
            serverSystem.players[String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name)].sp = [];
            serverSystem.executeCommand("/tellraw " + String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name) + ' {"rawtext":[{"text":"§c§lCorners cleared"}]}', () => { });
            return null
        } else if (serverSystem.players[String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name)].fp.length == 0) {
            //set first coords
            serverSystem.players[String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name)].fp = [eventData.data.block_position.x, eventData.data.block_position.y, eventData.data.block_position.z];
            serverSystem.executeCommand("/tellraw " + String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name) + ' {"rawtext":[{"text":"§b§lFirst pos set"}]}', () => { });
            return null
        } else if (serverSystem.players[String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name)].sp.length == 0) {
            //set the second coords
            serverSystem.players[String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name)].sp = [eventData.data.block_position.x, eventData.data.block_position.y, eventData.data.block_position.z];
            serverSystem.executeCommand("/tellraw " + String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name) + ' {"rawtext":[{"text":"§b§lSecond pos set"}]}', () => { });
            return null
        }
    }

    //if hollow block is placed
    if (serverSystem.getComponent(eventData.data.player, "minecraft:hand_container").data[0].item == "block:hollow") {
        if (serverSystem.players[String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name)].hl == false) {
            serverSystem.players[String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name)].hl = true;
            serverSystem.executeCommand("/tellraw " + String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name) + ' {"rawtext":[{"text":"§a§lSet outline mode to true"}]}', () => { });
            return null
        } else {
            serverSystem.players[String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name)].hl = false;
            serverSystem.executeCommand("/tellraw " + String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name) + ' {"rawtext":[{"text":"§a§lSet outline mode to false"}]}', () => { });
            return null
        }
    }

    //takes in block, eventdata (for blockstate), and playername (for coordinates and end message and clearing coords)
    if (serverSystem.players[String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name)].fp.length != 0 && serverSystem.players[String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name)].sp.length != 0) {
        serverSystem.exec_command(serverSystem.getComponent(eventData.data.player, "minecraft:hand_container").data[0].item, eventData, String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name));
    }

}


serverSystem.exec_command = function (fillItem, eventData, playerName) {
    fillItem = fillItem.replace("block:fillair", "air");
    fillItem = fillItem.replace("minecraft:concrete_powder", "minecraft:concretepowder");
    fillItem = fillItem.replace("minecraft:comparator", "minecraft:unpowered_comparator");
    fillItem = fillItem.replace("minecraft:repeater", "minecraft:unpowered_repeater");

    if (fillItem == "minecraft:redstone") {
        fillItem = "minecraft:redstone_wire";
    }
    fillItem = fillItem.replace("minecraft:", "");
    let viewingBlocksData = this.getComponent(serverSystem.getBlock(serverSystem.getComponent(eventData.data.player, "minecraft:tick_world").data.ticking_area, eventData.data.block_position.x, eventData.data.block_position.y, eventData.data.block_position.z), "minecraft:blockstate");

    let blockOutline = "";
    if (serverSystem.players[playerName].hl == true) {
        blockOutline = " outline"
    }

    serverSystem.executeCommand("/fill " + String(serverSystem.players[playerName].fp[0]) + " " + String(serverSystem.players[playerName].fp[1]) + " " + String(serverSystem.players[playerName].fp[2]) + " " + String(serverSystem.players[playerName].sp[0]) + " " + String(serverSystem.players[playerName].sp[1]) + " " + String(serverSystem.players[playerName].sp[2]) + " " + fillItem + " 0" + blockOutline, (commandResultData) => {
        let outMessage = "§a§lFilled " + commandResultData.data.fillCount + " blocks succesfully";
        serverSystem.executeCommand("/tellraw " + playerName + ' {"rawtext":[{"text":"' + outMessage + '"}]}', () => { });;
        if (commandResultData.data.fillCount != undefined) {
            serverSystem.replaceBlockState(eventData, viewingBlocksData, playerName);
        } else {
            serverSystem.players[playerName].fp = [];
            serverSystem.players[playerName].sp = [];
        };
    });


};



serverSystem.replaceBlockState = function (eventData, placedBlockData, playerName) {
    let firstFillBlock = this.getComponent(serverSystem.getBlock(serverSystem.getComponent(eventData.data.player, "minecraft:tick_world").data.ticking_area, serverSystem.players[playerName].sp[0], serverSystem.players[playerName].sp[1], serverSystem.players[playerName].sp[2]), "minecraft:blockstate");
    let blockCompareCondition = (JSON.stringify(placedBlockData) === JSON.stringify(firstFillBlock));
    if (placedBlockData.data != null && (blockCompareCondition == false)) {
        serverSystem.executeCommand("/tellraw " + playerName + ' {"rawtext":[{"text":"§b§lReplacing Block State (tileData)..."}]}', () => { })

        let increment1 = 0;
        let increment2 = 0;
        let increment3 = 0;

        if (serverSystem.players[playerName].sp[0] - serverSystem.players[playerName].fp[0] < 0) {
            increment1 -= 1;
        } else {
            increment1 += 1
        };
        if (serverSystem.players[playerName].sp[1] - serverSystem.players[playerName].fp[1] < 0) {
            increment2 -= 1;
        } else {
            increment2 += 1
        };
        if (serverSystem.players[playerName].sp[2] - serverSystem.players[playerName].fp[2] < 0) {
            increment3 -= 1;
        } else {
            increment3 += 1
        };

        for (let i = serverSystem.players[playerName].fp[0]; i != serverSystem.players[playerName].sp[0] + increment1; i += increment1) {
            for (let j = serverSystem.players[playerName].fp[1]; j != serverSystem.players[playerName].sp[1] + increment2; j += increment2) {
                for (let k = serverSystem.players[playerName].fp[2]; k != serverSystem.players[playerName].sp[2] + increment3; k += increment3) {

                    serverSystem.applyComponentChanges(serverSystem.getBlock(serverSystem.getComponent(eventData.data.player, "minecraft:tick_world").data.ticking_area, i, j, k), placedBlockData);

                };
            };
        };



    };

    serverSystem.players[String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name)].fp = [];
    serverSystem.players[String(serverSystem.getComponent(eventData.data.player, "minecraft:nameable").data.name)].sp = [];

};

